package gui.Reparation;

import gui.AddRemoveDialog;
import gui.MainFrame;

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.FlowLayout;
import java.awt.Font;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.ArrayList;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.List;
import java.util.Timer;
import java.util.TimerTask;

import javax.swing.BorderFactory;
import javax.swing.DefaultComboBoxModel;
import javax.swing.JButton;
import javax.swing.JComboBox;
import javax.swing.JDialog;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JTextField;
import javax.swing.border.EtchedBorder;
import javax.swing.border.TitledBorder;

import model.*;

import service.Service;

/**
 * 
 * @author Csaba Tarkanyi
 * 
 */
public class ReparationCUDialog extends JDialog {

	private JButton ok, finish, addRemSp, remAllSp, addRemRt, remAllRt;
	private JLabel clock, info;
	private JPanel pCenter;
	private JLabel lID, lMachine, lSpareParts, lRepairTypes;
	private JTextField txtID;
	private JComboBox cbxMachine, cbxSpareParts, cbxRepairTypes;

	private DefaultComboBoxModel modelMachine = new DefaultComboBoxModel();
	private DefaultComboBoxModel modelSpareParts = new DefaultComboBoxModel();
	private DefaultComboBoxModel modelRepairTypes = new DefaultComboBoxModel();

	private Service service = Service.getService();

	private Controller controller = new Controller();

	public ReparationCUDialog(javax.swing.JFrame owner, String title) {
		super(owner, title, true);
		setDefaultCloseOperation(JDialog.HIDE_ON_CLOSE);
		setBounds(220, 150, 380, 380);
		getContentPane().setLayout(new BorderLayout());
		setModal(true);

		pCenter = new JPanel(null);
		pCenter.setBorder(BorderFactory.createTitledBorder(BorderFactory
				.createEtchedBorder(EtchedBorder.LOWERED), "Details"));
		getContentPane().add(pCenter, BorderLayout.CENTER);

		getFields();
		getButton();
		getClock();

		fillListMachine();
	}

	/**
	 * Gets all the JLabels, JTextFields, JComboBoxes and JButtons.
	 * 
	 * @author Csaba Tarkanyi
	 */
	private void getFields() {

		int labelW = 70;
		int fieldW = 250;
		int idY = 20, mY = 50, spY = 80, arspY = 110, rtY = 140, arrtY = 170;

		lID = new JLabel("ID:");
		lID.setBounds(20, idY, labelW, 22);
		pCenter.add(lID);

		lMachine = new JLabel("Machine:");
		lMachine.setBounds(20, mY, labelW, 22);
		pCenter.add(lMachine);

		lSpareParts = new JLabel("Spare Parts:");
		lSpareParts.setBounds(20, spY, labelW, 22);
		pCenter.add(lSpareParts);

		lRepairTypes = new JLabel("Repair Types:");
		lRepairTypes.setBounds(20, rtY, labelW, 22);
		pCenter.add(lRepairTypes);

		txtID = new JTextField("9999999");
		txtID.setBounds(30 + labelW, idY, fieldW, 22);
		pCenter.add(txtID);

		cbxMachine = new JComboBox(modelMachine);
		cbxMachine.setBounds(30 + labelW, mY, fieldW, 22);
		cbxMachine.addActionListener(controller);
		pCenter.add(cbxMachine);

		cbxSpareParts = new JComboBox(modelSpareParts);
		cbxSpareParts.setBounds(30 + labelW, spY, fieldW, 22);
		pCenter.add(cbxSpareParts);

		addRemSp = new JButton("add/remove");
		addRemSp.setBounds(30 + labelW, arspY, 120, 22);
		addRemSp.addActionListener(new ActionListener() {
			@Override
			public void actionPerformed(ActionEvent e) {
				if (e.getSource() == addRemSp) {
					// Gets the selected Machine.
					Machine machine = (Machine) modelMachine.getSelectedItem();
					// Temp List for SpareParts.
					List<Object> listSPU = new ArrayList<Object>();
					listSPU.addAll(machine.getMachineType().getSpareParts());
					// Temp List for the selected SparePartUses of Reparation.
					List<Object> listSPUNeed = new ArrayList<Object>();
					for (int i = 0; i < modelSpareParts.getSize(); i++) {
						listSPUNeed.add(modelSpareParts.getElementAt(i));
					}
					// Shows new AddRemoveDialog and sets the left List.
					AddRemoveDialog ard = new AddRemoveDialog(
							ReparationCUDialog.this, "Add/Rem Spare Part",
							"Spare Parts", "Added", listSPU, listSPUNeed);
					modelSpareParts.removeAllElements();
					ard.setVisible(true);
					// Fills the List after OK.
					if (ard.isOk()) {
						for (Object n : ard.getRightListModel()) {
							modelSpareParts.addElement(n);
						}
					}
				}
			}
		});
		pCenter.add(addRemSp);

		remAllSp = new JButton("remove all");
		remAllSp.setBounds(40 + labelW + 120, arspY, 120, 22);
		remAllSp.addActionListener(new ActionListener() {
			@Override
			public void actionPerformed(ActionEvent e) {
				if (e.getSource() == remAllSp) {
					// Removes all the element form the model.
					modelSpareParts.removeAllElements();
				}
			}
		});
		pCenter.add(remAllSp);

		cbxRepairTypes = new JComboBox(modelRepairTypes);
		cbxRepairTypes.setBounds(30 + labelW, rtY, fieldW, 22);
		pCenter.add(cbxRepairTypes);

		addRemRt = new JButton("add/remove");
		addRemRt.setBounds(30 + labelW, arrtY, 120, 22);
		addRemRt.addActionListener(new ActionListener() {
			@Override
			public void actionPerformed(ActionEvent e) {
				if (e.getSource() == addRemRt) {
					// Gets the selected Machine.
					Machine machine = (Machine) modelMachine.getSelectedItem();
					// Temp List for RepairTypes.
					List<Object> listRT = new ArrayList<Object>();
					listRT.addAll(machine.getMachineType().getRepairTypes());
					// Temp List for the selected RepairTypes of Reparation.
					List<Object> listRTNeed = new ArrayList<Object>();
					for (int i = 0; i < modelRepairTypes.getSize(); i++) {
						listRTNeed.add(modelRepairTypes.getElementAt(i));
					}
					// Shows new AddRemoveDialog and sets the left List.
					AddRemoveDialog ard = new AddRemoveDialog(
							ReparationCUDialog.this, "Add/Rem Repair Type",
							"Repair Types", "Added", listRT, listRTNeed);
					modelRepairTypes.removeAllElements();
					ard.setVisible(true);
					// Fill the list after OK.
					if (ard.isOk()) {
						for (Object n : ard.getRightListModel()) {
							modelRepairTypes.addElement(n);
						}
					}
				}
			}
		});
		pCenter.add(addRemRt);
		// Button for remove all the RepairType.
		remAllRt = new JButton("remove all");
		remAllRt.setBounds(40 + labelW + 120, arrtY, 120, 22);
		remAllRt.addActionListener(new ActionListener() {
			@Override
			public void actionPerformed(ActionEvent e) {
				if (e.getSource() == remAllRt) {
					// Removes all the element form the model.
					modelRepairTypes.removeAllElements();
				}
			}
		});
		pCenter.add(remAllRt);
	}

	/**
	 * Gets the Info JLabel and the two JButtons.
	 * 
	 * @author Csaba Tarkanyi
	 */
	private void getButton() {
		JPanel pSouthUp = new JPanel(new FlowLayout(FlowLayout.LEFT));
		// Info Label and its Border.
		info = new JLabel("...");
		pSouthUp.setBorder(BorderFactory.createTitledBorder(BorderFactory
				.createEtchedBorder(EtchedBorder.LOWERED), "Info"));
		pSouthUp.add(info);
		// Finish Button.
		JPanel pSouthDown = new JPanel(new FlowLayout(FlowLayout.RIGHT));
		finish = new JButton("Finish.");
		finish.setEnabled(false);
		// OK Button.
		ok = new JButton("Create");
		ok.addActionListener(new ActionListener() {
			@Override
			public void actionPerformed(ActionEvent e) {
				if (e.getSource() == ok) {
					// Gets Id for Reparation.
					long id = Long.parseLong(txtID.getText());
					// TODO check ID...
					// Gets Machine for Reparation.
					Machine machine = (Machine) modelMachine.getSelectedItem();
					// Create new Reparation.
					for (Machine m : service.getMachines()) {
						if (m.equals(machine)) {
							try {
								Reparation r = new Reparation(id,
										new GregorianCalendar(), "", machine);
								// Adds all the SparePartUses to the Reparation.
								if (modelSpareParts.getSize() != 0) {
									for (int i = 0; i < modelSpareParts
											.getSize(); i++) {
										SparePartUse spu = (SparePartUse) modelSpareParts
												.getElementAt(i);
										r.addTempSparePartUse(spu);
									}
								}
								// Adds all the RepairTypes to the Reparation.
								if (modelRepairTypes.getSize() != 0) {
									for (int i = 0; i < modelRepairTypes
											.getSize(); i++) {
										RepairType rt = (RepairType) modelRepairTypes
												.getElementAt(i);
										r.addRepairType(rt);
									}
								}
								// Commit everything -> the SpareParts added to
								// the Reparation.
								r.update();
								// Hide the JDialog.
								ReparationCUDialog.this.setVisible(false);
							} catch (Exception ex) {
								JOptionPane.showMessageDialog(
										ReparationCUDialog.this, ex
												.getMessage(), "Error",
										JOptionPane.ERROR_MESSAGE);
							}
						}
					}
				}
			}
		});
		// Creates the South JPanel and adds Components to that.
		JPanel pSouth = new JPanel(new BorderLayout());
		pSouth.add(pSouthUp, BorderLayout.NORTH);
		pSouth.add(pSouthDown, BorderLayout.SOUTH);
		// Adds the Button to the pSouthDown Panel.
		pSouthDown.add(finish);
		pSouthDown.add(ok);
		// Sets the South Panel on the ContentPane.
		getContentPane().add(pSouth, BorderLayout.SOUTH);
	}

	/**
	 * Gets the exact time and update it every second on a JLabel.
	 * 
	 * @author Csaba Tarkanyi
	 */
	private void getClock() {
		// Creates the north JPanel.
		JPanel pNorth = new JPanel(new FlowLayout(FlowLayout.CENTER));
		getContentPane().add(pNorth, BorderLayout.NORTH);
		// Creates a Border around the clock.
		TitledBorder titled;
		titled = BorderFactory.createTitledBorder(BorderFactory
				.createEtchedBorder(EtchedBorder.LOWERED), "Exact Time");
		// JLabel to show the clock.
		clock = new JLabel("");
		clock.setFont(new Font("Arial", Font.BOLD + Font.ITALIC, 12));
		clock.setForeground(Color.BLACK);
		pNorth.setBorder(titled);
		pNorth.add(clock);
		// Refresh the clock.
		manageTime();
	}

	/**
	 * Refresh the Time in every second.
	 * 
	 * @author Csaba Tarkanyi
	 */
	public void manageTime() {
		Timer timer = new Timer();
		timer.schedule(new DoTick(), 0, 1000); // update time every second

	}

	// Creates an inner class for the Time.
	public class DoTick extends TimerTask {
		@Override
		public void run() {
			long d = new Date().getTime();// Gets the Date today.
			// Sets the Date's format with SimpleDateFormat.
			String s2 = MainFrame.getSimpleDateFormat().format(d);
			// Sets the formated text to the JLabel to show the time.
			clock.setText(s2);
		}
	}

	/**
	 * Fills modelMachine List with all the Machines.
	 * 
	 * @author Csaba Tarkanyi
	 */
	private void fillListMachine() {
		for (Machine m : service.getMachines()) {
			modelMachine.addElement(m);
		}
	}

	private class Controller implements ActionListener {
		private String options[] = { "    Yes, please    ", "    Nope   " };

		@Override
		public void actionPerformed(ActionEvent e) {
			if (e.getSource() == cbxMachine) {
				// TODO if the user chooses an other MachineType and there is
				// something in the SparePartList or the RepairType List delete
				// all if the user wants it.
				// fillListSpareParts();
				if (modelSpareParts.getSize() != 0
						|| modelRepairTypes.getSize() != 0) {
					int value = JOptionPane
							.showOptionDialog(
									null,
									"You choosed another MachineType, do you really want to delete"
											+ " the SparePart(s) and/or the ReparirType(s)?",
									"Exiting...", JOptionPane.YES_NO_OPTION,
									JOptionPane.INFORMATION_MESSAGE, null,
									options, options[1]);

					if (value == JOptionPane.YES_OPTION) {
						modelSpareParts.removeAllElements();
						modelRepairTypes.removeAllElements();
					}
				}
			}
		}
	}
}